package com.hua.Service;

import org.apache.http.Header;

/**
 * Hello world!
 *
 */
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;

import com.hua.Model.UploadInfo;
import com.hua.Model.UserInfo;
import com.hua.ui.UploadProgressWindow;
import com.hua.ui.main;
import com.hua.ui.routine;

import junit.framework.Test;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import org.apache.http.HttpEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.ContentType;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class upload_download {

	// 上传同步
	public static Future<Boolean> uploadAsync(String filePath, UserInfo user, String type) {
		ExecutorService executor = Executors.newFixedThreadPool(1);
		return executor.submit(() -> upload(filePath, user, type));
	}

	public static Boolean upload(String filePath, UserInfo user, String type) {
		// 音频播放器
		AudioPlayer player = new AudioPlayer();
		// 更新任务列表
		// 信息获取
		File file_info = new File(filePath);
		String fileName = file_info.getName();
		double fileSizeInMB = (double) file_info.length() / (1024 * 1024);
		String formattedFileSize = String.format("%.2f", fileSizeInMB);

		// 上传模块
		System.out.println(filePath);
		String serverUrl = "http://10.157.0.7:6767/upload";

		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost uploadFile = new HttpPost(serverUrl);
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();

		// 选中文件，附加到POST请求，实现文件流
		File f = new File(filePath);
		// URL中文编码
		String encodedFileName = URLEncoder.encode(f.getName());

		// 实例化弹窗进度
		UploadProgressWindow window = new UploadProgressWindow("正在上传:" + fileName, filePath, formattedFileSize);
		window.setVisible(true);
		//
		FileBody fileBody = new FileBody(f, ContentType.APPLICATION_OCTET_STREAM, encodedFileName) {
			@Override
			public void writeTo(final OutputStream out) throws IOException {
				super.writeTo(new CountingOutputStream(out, total -> {
					// 进度
					double progress = (double) total / f.length() * 100;
					// System.out.println("Upload progress: " + progress + "%");
					// 更新进度条进度
					window.updateProgress((int) Math.floor(progress));
					// task.updateProgress(0, (int) Math.floor(progress));
				}));
			}
		};
		builder.addPart("file", fileBody);

		// 添加其他POST字段
		System.out.println(user.getAccount() + user.getPassword());
		builder.addTextBody("account", user.getAccount());
		builder.addTextBody("password", user.getPassword());
		builder.addTextBody("type", type);

		HttpEntity multipart = builder.build();
		uploadFile.setEntity(multipart);

		HttpResponse response = null;
		try {
			response = httpClient.execute(uploadFile);
			HttpEntity responseEntity = response.getEntity();
			// System.out.println("POST Response is: " +
			// EntityUtils.toString(responseEntity));
		} catch (IOException e) {
			e.printStackTrace();
			player.play("faild");
			return false;
		}
		// 任务列表添加
		List<UploadInfo> files = new ArrayList<>();
		// 其中1.11表示下载，0.00表示上传(因为懒得改结构了，临时需要)
		UploadInfo uploadInfo = new UploadInfo(fileName, type, formattedFileSize, "上传","");
		//
		files.add(uploadInfo);
		main.files_upload.add(uploadInfo);
		window.dispose();
		// 成功完成
		player.play("over");
		return true;
	}

	// 文件流
	public static class CountingOutputStream extends OutputStream {
		private final OutputStream out;
		private final ProgressListener listener;
		private long transferred;

		public CountingOutputStream(final OutputStream out, final ProgressListener listener) {
			this.out = out;
			this.listener = listener;
			this.transferred = 0;
		}

		public void write(int b) throws IOException {
			out.write(b);
			transferred++;
			listener.transferred(transferred);
		}

		public void write(byte[] b) throws IOException {
			out.write(b);
			transferred += b.length;
			listener.transferred(transferred);
		}

		public void write(byte[] b, int off, int len) throws IOException {
			out.write(b, off, len);
			transferred += len;
			listener.transferred(transferred);
		}

		public interface ProgressListener {
			void transferred(long num);
		}
	}

	// 下载逻辑
	public static Boolean download(UserInfo user, int filesID, String filename, Double size, String type) {
		// 音频播放器
		AudioPlayer player = new AudioPlayer();
		// 获取相应路径
		String serverUrl = "http://10.157.0.7:6767/download?account=" + user.getAccount() + "&token="
				+ user.getPassword() + "&filesID=" + Integer.toString(filesID);
		String desktopPath = System.getProperty("user.home") + "\\Desktop\\";
		String downloadPath = desktopPath + filename;
		System.out.println("下载文件：" + serverUrl + "->" + downloadPath);
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpGet downloadFile = new HttpGet(serverUrl);

		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(downloadFile);
			HttpEntity responseEntity = response.getEntity();
			// 文件返回
			if (responseEntity != null) {
				long fileLength = responseEntity.getContentLength();
				InputStream is = responseEntity.getContent();
				FileOutputStream fos = new FileOutputStream(new File(downloadPath));
				byte[] buffer = new byte[1024];
				int len;
				long downloaded = 0;
				// 实例化弹窗进度
				UploadProgressWindow window = new UploadProgressWindow("正在下载:" + filename, downloadPath,
						Double.toString(size));
				window.setVisible(true);
				// 判断文件块长度
				while ((len = is.read(buffer)) != -1) {
					fos.write(buffer, 0, len);
					downloaded += len;
					int progress = (int) (downloaded * 100 / fileLength);
					// 进度实例
					System.out.println("Download progress: " + progress + "%");
					window.updateProgress((int) Math.floor(progress));
				}
				// 文件流的关闭
				is.close();
				fos.close();
				System.out.println("File downloaded successfully");
				UploadInfo downloadfile = new UploadInfo(filename, type, Double.toString(size), "下载",desktopPath);
				// 添加到任务窗口
				main.files_upload.add(downloadfile);
				// 关闭窗口与线程，播放音效
				window.dispose();
				player.play("over");
				return true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (response != null) {
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}
}
